defmodule NucleotideCount do
  @doc """
  Counts individual nucleotides in a DNA strand.

  ## Examples

  iex> NucleotideCount.count('AATAA', ?A)
  4

  iex> NucleotideCount.count('AATAA', ?T)
  1
  """
  @spec count(charlist(), char()) :: non_neg_integer()
  def count(strand, nucleotide) do
    Enum.reduce(strand, 0, 
      fn(x, acc) when x === nucleotide -> 1 + acc end
      )
  end

  @doc """
  Returns a summary of counts by nucleotide.

  ## Examples

  iex> NucleotideCount.histogram('AATAA')
  %{?A => 4, ?T => 1, ?C => 0, ?G => 0}
  """
  @spec histogram(charlist()) :: map()
  def histogram(strand) do
    count2map(%{?A => 0, ?T => 0, ?C => 0, ?G => 0}, strand)
  end

  defp count2map(c2map, []), do:  c2map
  defp count2map(c2map, [h|t]) do

    Map.update(c2map, h, 0, &(&1 + 1))
      |> count2map(t)

  end

end
